package com.stylefeng.guns.rest.common.base.controller;

import com.alibaba.fastjson.JSON;
import com.stylefeng.guns.rest.common.exception.BizExceptionEnum;
import com.stylefeng.guns.rest.common.exception.ParamException;
import com.stylefeng.guns.rest.common.exception.SysException;
import com.stylefeng.guns.rest.common.util.WebUtil;
import com.stylefeng.guns.rest.domain.Res;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.ui.Model;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 控制器支持类
 */
public abstract class ApiBaseController {

	/**
	 * 日志对象
	 */
	protected Logger LOGGER = LoggerFactory.getLogger(getClass());

	/**
	 * 管理基础路径
	 */
//	@Value("${adminPath}")
//	protected String adminPath;

	/**
	 * 前端基础路径
	 */
//	@Value("${frontPath}")
//	protected String frontPath;

	/**
	 * 前端URL后缀
	 */
//	@Value("${urlSuffix}")
//	protected String urlSuffix;


	/**
	 * 添加Model消息
	 * @param
	 */
	protected void addMessage(Model model, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages){
			sb.append(message).append(messages.length>1?"<br/>":"");
		}
		model.addAttribute("message", sb.toString());
	}

	/**
	 * 添加Flash消息
	 * @param
	 */
	protected void addMessage(RedirectAttributes redirectAttributes, String... messages) {
		StringBuilder sb = new StringBuilder();
		for (String message : messages){
			sb.append(message).append(messages.length>1?"<br/>":"");
		}
		redirectAttributes.addFlashAttribute("message", sb.toString());
	}

	/**
	 * 客户端返回JSON字符串
	 * @param response
	 * @param object
	 * @return
	 */
//	protected String renderString(HttpServletResponse response, Object object) {
//		return renderString(response, JsonMapper.toJsonString(object), "application/json");
//	}

	/**
	 * 客户端返回字符串
	 * @param response
	 * @param string
	 * @return
	 */
	protected String renderString(HttpServletResponse response, String string, String type) {
		try {
			response.reset();
	        response.setContentType(type);
	        response.setCharacterEncoding("utf-8");
			response.getWriter().print(string);
			return null;
		} catch (IOException e) {
			return null;
		}
	}

	/**
	 * 记录删除日志
	 * @param objectDesc 描述删除对象是什么
	 * @param deleteObject
	 * @param deleteCount
	 */
//	public void LogDelete(String objectDesc, Object deleteObject, int deleteCount) {
//		Admin admin = AdminUtils.getAdmin();
//		String userInfo = "[name=" + admin.getName() + "|id=" + admin.getId()
//				+ "|loginname=" + admin.getLoginname() + "|loginIp=" + admin.getLoginIp() + "]";
//		LOGGER.warn("删除操作日志==>>> {}: {}, 删除记录数: {}, 操作用户: {}",
//				objectDesc, JsonMapper.toJson(deleteObject), deleteCount, userInfo);
//	}

	/**
	 * 初始化数据绑定
	 * 1. 将所有传递进来的String进行HTML编码，防止XSS攻击
	 * 2. 将字段中Date类型转换为String类型
	 */
//	@InitBinder
//	protected void initBinder(WebDataBinder binder) {
//		// String类型转换，将所有传递进来的String进行HTML编码，防止XSS攻击
//		binder.registerCustomEditor(String.class, new PropertyEditorSupport() {
//			@Override
//			public void setAsText(String text) {
//				setValue(text == null ? null : StringEscapeUtils.escapeHtml4(text.trim()));
//			}
//			@Override
//			public String getAsText() {
//				Object value = getValue();
//				return value != null ? value.toString() : "";
//			}
//		});
//		// Date 类型转换
//		binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
//			@Override
//			public void setAsText(String text) {
//				setValue(DateUtils.parseDate(text));
//			}
////			@Override
////			public String getAsText() {
////				Object value = getValue();
////				return value != null ? DateUtils.formatDateTime((Date)value) : "";
////			}
//		});
//	}

	/**
	 * 异常处理
	 *
	 * @param exception
	 *            异常
	 * @param response
	 *            HttpServletResponse
	 * @return 数据视图
	 */
	@ExceptionHandler
//	public ModelAndView exceptionHandler(Exception exception, HttpServletResponse response) {
	public void exceptionHandler(Exception exception, HttpServletResponse response) {
		Res res = new Res();
		res.setCode(BizExceptionEnum.RES_FAIL.getCode());
		if (exception instanceof ParamException) {//参数传输错误
		    BizExceptionEnum bizExceptionEnum = ((ParamException) exception).getBizExceptionEnum();
			res.setCode(bizExceptionEnum.getCode()).setMsg(bizExceptionEnum.getMsg()+":"+((ParamException) exception).getAttr());
		}else if (exception instanceof HttpMessageNotReadableException) {//传入json数据类型异常
			res.setMsg(BizExceptionEnum.HttpMessageNotReadableException.getMsg()).setCode(BizExceptionEnum.HttpMessageNotReadableException.getCode());
		}else if (exception instanceof HttpMediaTypeNotSupportedException) {//传入json数据类型异常
			res.setMsg(BizExceptionEnum.HttpMessageNotReadableException.getMsg()).setCode(BizExceptionEnum.HttpMessageNotReadableException.getCode());
		}else if (exception instanceof MissingServletRequestParameterException) {
			res.setCode(BizExceptionEnum.ISV_MISSING.getCode()).setMsg("缺少参数："+((MissingServletRequestParameterException) exception).getParameterName());
		}else if (exception instanceof SysException) {
			res.setCode(((SysException) exception).getBizExceptionEnum().getCode()).setMsg(((SysException) exception).getBizExceptionEnum().getMsg());
		}/*else if (exception instanceof ResourceNotFoundException) {
//			response.setStatus(HttpServletResponse.SC_NOT_FOUND);
//			return new ModelAndView("/admin/common/resource_not_found");
			res.setMsg("找不到资源");
		} else if(exception instanceof ApiException){
			res.setMsg("接口异常");
		} */else {
//			LOGGER.warn("请重新登录!", exception);
//			res.setMsg("请重新登录!");
			res.setMsg("系统繁忙!");
//			ModelMap model = new ModelMap();
//			model.addAttribute("exception", exception);
//			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
//			return new ModelAndView(ERROR_VIEW, model);
		}
		WebUtil.responseByJSON(response, JSON.toJSONString(res));
	}
}
